package com.example.travel_front.Activity;

import static androidx.core.content.ContentProviderCompat.requireContext;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.travel_front.APP;
import com.example.travel_front.Adapter.AttractionAdapter;
import com.example.travel_front.Fragment.SearchResultFragment;
import com.example.travel_front.Model.Attraction;
import com.example.travel_front.R;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;

public class SearchActivity extends AppCompatActivity implements View.OnClickListener {

    enum Type {
        LIKE,
        DISLIKE
    }

    private static final String[] CN_DAY = {"Sun.", "Mon.", "Tue.", "Wed.", "Thu.", "Fri.", "Sat."};
    private FrameLayout rootContainer;
    private TextView locationTextView;
    private ExtendedFloatingActionButton searchBtn;
    private ConstraintLayout startDateLayout;
    private ConstraintLayout endDateLayout;
    private TextView startDateView;
    private TextView endDateView;
    private TextView startWeekDayView;
    private TextView endWeekDayView;
    private TextView totalNightView;
    private ChipGroup likeTypeContainer;
    private ChipGroup dislikeTypeContainer;
    private TextView likeTypeTextHint;
    private TextView dislikeTypeTextHint;
    private EditText specialEdit;
    private RecyclerView attractionRecyclerView;
    private LinearLayout chooseTagContainer;
    private Calendar startCal;
    private Calendar endCal;
    private AttractionAdapter adapter;
    private boolean isFirstStart = true;
    private Type currentType = null;
    private final List<Attraction> likeTypeList = new ArrayList<>();
    private final List<Attraction> dislikeTypeList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        fitSystemWindows();
        setContentView(R.layout.activity_search);
        initViews();
        initData();
        initRecyclerVIew();
        initListeners();

        //back
        //返回
        findViewById(R.id.toolbar).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                finish();
            }
        });
    }

    /**
     * 沉浸式状态栏
     */
    private void fitSystemWindows() {
        WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), (v, insets) -> {
            Insets systemWindow = insets.getInsets(WindowInsetsCompat.Type.systemBars() |
                    WindowInsetsCompat.Type.displayCutout());
            if (isFirstStart) {
                //为需要偏移的view设置padding
                rootContainer.setPadding(
                        rootContainer.getPaddingLeft(), rootContainer.getPaddingTop() + systemWindow.top,
                        rootContainer.getPaddingRight(), rootContainer.getPaddingBottom());
                isFirstStart = false;
            }
            return insets;
        });
    }

    private void initViews() {
        rootContainer = findViewById(R.id.rootContainer);
        locationTextView = findViewById(R.id.locationText);
        searchBtn = findViewById(R.id.searchBtn);
        startDateLayout = findViewById(R.id.startDateLayout);
        endDateLayout = findViewById(R.id.endDateLayout);
        startDateView = findViewById(R.id.startDate);
        endDateView = findViewById(R.id.endDate);
        startWeekDayView = findViewById(R.id.startWeekDay);
        endWeekDayView = findViewById(R.id.endWeekDay);
        totalNightView = findViewById(R.id.totalNight);
        likeTypeContainer = findViewById(R.id.likeTypeContainer);
        dislikeTypeContainer = findViewById(R.id.dislikeTypeContainer);
        likeTypeTextHint = findViewById(R.id.likeTypeTextHint);
        dislikeTypeTextHint = findViewById(R.id.dislikeTypeTextHint);
        specialEdit = findViewById(R.id.specialEdit);
        attractionRecyclerView = findViewById(R.id.attractionRecyclerView);
        chooseTagContainer = findViewById(R.id.chooseTagContainer);
    }

    private void initRecyclerVIew() {
        adapter = new AttractionAdapter(generateFakeList());
        attractionRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));
        chooseTagContainer.setVisibility(View.GONE);
        attractionRecyclerView.setAdapter(adapter);
        attractionRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                super.getItemOffsets(outRect, view, parent, state);
                RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
                if (!(layoutManager instanceof GridLayoutManager)) {
                    return;
                }
                GridLayoutManager gridLayoutManager = (GridLayoutManager) parent.getLayoutManager();
                int position = gridLayoutManager.getPosition(view);
                if (position < 0) return;
                int spanCount = gridLayoutManager.getSpanCount();
                int padding = 20;
                // 第一行顶部间距
                if (position <= 3) {
                    outRect.top = padding;
                }
                // 第一列左边间距
                if (position % spanCount == 0) {
                    outRect.left = padding;
                }
                outRect.bottom = padding;
                outRect.right = padding;
            }
        });
    }

    private void initData() {
        startCal = Calendar.getInstance();
        endCal = Calendar.getInstance();
        endCal.add(Calendar.DAY_OF_YEAR, 1);
        updateDateUI();
    }

    private void initListeners() {

        startDateLayout.setOnClickListener(this);
        endDateLayout.setOnClickListener(this);

        adapter.setOnItemClickListener((attraction, position) -> {
            if (currentType == null) {
                return;
            }
            switch (currentType) {
                case LIKE:
                    int likeIndex = likeTypeList.indexOf(attraction);
                    if (likeIndex == -1) {
                        addTag(attraction);
                    } else {
                        removeTag(attraction, likeIndex);
                    }
                    break;
                case DISLIKE:
                    int dislikeIndex = dislikeTypeList.indexOf(attraction);
                    if (dislikeIndex == -1) {
                        addTag(attraction);
                    } else {
                        removeTag(attraction, dislikeIndex);
                    }
                    break;
                default:
                    break;
            }
        });

        specialEdit.setOnFocusChangeListener((view, b) -> {
            if (b) {
                likeTypeContainer.setBackground(null);
                dislikeTypeContainer.setBackground(null);
                chooseTagContainer.setVisibility(View.GONE);
            }
        });

        likeTypeContainer.setOnClickListener(this);
        dislikeTypeContainer.setOnClickListener(this);
        searchBtn.setOnClickListener(this);
    }

    private void addTag(Attraction attraction) {
        Chip chip = new Chip(SearchActivity.this);
        chip.setText(attraction.name);
        chip.setCheckable(false);
        chip.setHeight((int) dpToPx());
        switch (currentType) {
            case LIKE:
                if (likeTypeList.isEmpty()) {
                    likeTypeTextHint.setVisibility(View.GONE);
                }
                likeTypeContainer.addView(chip);
                likeTypeList.add(attraction);
                break;
            case DISLIKE:
                if (dislikeTypeList.isEmpty()) {
                    dislikeTypeTextHint.setVisibility(View.GONE);
                }
                dislikeTypeContainer.addView(chip);
                dislikeTypeList.add(attraction);
                break;
            default:
                break;
        }
    }

    private void removeTag(Attraction attraction, int index) {
        switch (currentType) {
            case LIKE:
                likeTypeContainer.removeViewAt(index);
                likeTypeList.remove(attraction);
                if (likeTypeList.isEmpty()) {
                    likeTypeTextHint.setVisibility(View.VISIBLE);
                }
                break;
            case DISLIKE:
                dislikeTypeContainer.removeViewAt(index);
                dislikeTypeList.remove(attraction);
                if (likeTypeList.isEmpty()) {
                    dislikeTypeTextHint.setVisibility(View.VISIBLE);
                }
                break;
            default:
                break;
        }
    }

    private void updateDateUI() {
        // 日期
        startDateView.setText(
                getString(R.string.choose_date,
                        startCal.get(Calendar.MONTH) + 1,
                        startCal.get(Calendar.DAY_OF_MONTH)
                ));
        endDateView.setText(
                getString(R.string.choose_date,
                        endCal.get(Calendar.MONTH) + 1,
                        endCal.get(Calendar.DAY_OF_MONTH)
                ));
        // 星期
        int startWeekday = startCal.get(Calendar.DAY_OF_WEEK);
        startWeekDayView.setText(CN_DAY[startWeekday - 1]);
        int endWeekday = endCal.get(Calendar.DAY_OF_WEEK);
        endWeekDayView.setText(CN_DAY[endWeekday - 1]);
        // 晚数
        int weekday = (int) ((endCal.getTimeInMillis() - startCal.getTimeInMillis()) / (1000 * 60 * 60 * 24));
        totalNightView.setText(getString(R.string.total_night, weekday));
    }

    private List<Attraction> generateFakeList() {
        List<Attraction> list = new ArrayList<>();
        String[] attractions = {
                "Natural Scenery", "Historical Culture", "Adventure Exploration",
                "Culinary Journey", "Shopping Experience", "Art and Performance",
                "Health and Wellness", "Family Travel", "Urban Scenery",
                "Outdoor Camping", "Spiritual Retreats", "Water Activities",
                "Mountain Trekking", "Rural Countryside", "Ancient Town Wanderings",
                "Snowy Expedition", "River Rafting"
        };
        for (int i = 0; i < 20; i++) {
            String attractionName = attractions[i % attractions.length];
            list.add(new Attraction(attractionName, "", ""));
        }
        return list;
    }

    @Override
    public void onClick(View view) {
        int clickId = view.getId();
        if (clickId != R.id.likeTypeContainer || clickId != R.id.dislikeTypeContainer) {
            chooseTagContainer.setVisibility(View.GONE);
            likeTypeContainer.setBackground(null);
            dislikeTypeContainer.setBackground(null);
        }

        if (clickId == R.id.startDateLayout) {
            new DatePickerDialog(SearchActivity.this, R.style.DialogTheme, (datePicker, year, month, dayOfMonth) -> {
                startCal.set(year, month, dayOfMonth);
                updateDateUI();
            }, startCal.get(Calendar.YEAR),
                    startCal.get(Calendar.MONTH),
                    startCal.get(Calendar.DAY_OF_MONTH)
            ).show();
        } else if (clickId == R.id.endDateLayout) {
            new DatePickerDialog(SearchActivity.this, R.style.DialogTheme, (datePicker, year, month, dayOfMonth) -> {
                endCal.set(year, month, dayOfMonth);
                updateDateUI();
            }, endCal.get(Calendar.YEAR),
                    endCal.get(Calendar.MONTH),
                    endCal.get(Calendar.DAY_OF_MONTH)
            ).show();
        } else if (clickId == R.id.likeTypeContainer) {
            if (specialEdit.hasFocus()) {
                hideKeyBoard(SearchActivity.this);
                specialEdit.clearFocus();
            }
            currentType = Type.LIKE;
            adapter.loadData(generateFakeList(), likeTypeList);
            chooseTagContainer.setVisibility(View.VISIBLE);
            likeTypeContainer.setBackgroundResource(R.drawable.bg_type_container);
            dislikeTypeContainer.setBackground(null);
        } else if (clickId == R.id.dislikeTypeContainer) {
            if (specialEdit.hasFocus()) {
                hideKeyBoard(SearchActivity.this);
                specialEdit.clearFocus();
            }
            currentType = Type.DISLIKE;
            adapter.loadData(generateFakeList(), dislikeTypeList);
            chooseTagContainer.setVisibility(View.VISIBLE);
            dislikeTypeContainer.setBackgroundResource(R.drawable.bg_type_container);
            likeTypeContainer.setBackground(null);
        } else if (clickId == R.id.searchBtn) {
            String location = locationTextView.getText().toString();
            ProgressDialog progressDialog = new ProgressDialog(this, R.style.ProgressDialogStyle);
            progressDialog.setMessage("route planning... ...");
            progressDialog.show();
            //TODO 设置城市
            APP.city = location.split("，")[0];
            new Thread(() -> this.runOnUiThread(() -> {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                progressDialog.dismiss();
            })).start();
            this.getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.rootContainer, new SearchResultFragment())
                    .addToBackStack("SearchResultFragment")
                    .commit();
        }

}

    public void hideKeyBoard(Activity act) {
        InputMethodManager inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(Objects.requireNonNull(act.getCurrentFocus()).getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }

    private float dpToPx() {
        return TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                50,
                getResources().getDisplayMetrics()
        );
    }
}